home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume13 / gmcalc / part08 < prev    next >
Encoding:
Text File  |  1990-06-05  |  57.1 KB  |  1,896 lines

  1. Newsgroups: comp.sources.misc
  2. From: daveg@csvax.caltech.edu (David Gillespie)
  3. Subject: v13i034: Emacs Calculator 1.01, part 08/19
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 13, Issue 34
  7. Submitted-by: daveg@csvax.caltech.edu (David Gillespie)
  8. Archive-name: gmcalc/part08
  9.  
  10. ---- Cut Here and unpack ----
  11. #!/bin/sh
  12. # this is part 8 of a multipart archive
  13. # do not concatenate these parts, unpack them in order with /bin/sh
  14. # file calc-ext.el continued
  15. #
  16. CurArch=8
  17. if test ! -r s2_seq_.tmp
  18. then echo "Please unpack part 1 first!"
  19.      exit 1; fi
  20. ( read Scheck
  21.   if test "$Scheck" != $CurArch
  22.   then echo "Please unpack part $Scheck next!"
  23.        exit 1;
  24.   else exit 0; fi
  25. ) < s2_seq_.tmp || exit 1
  26. echo "x - Continuing file calc-ext.el"
  27. sed 's/^X//' << 'SHAR_EOF' >> calc-ext.el
  28. X                   (- (+ (math-numdigs (nth 1 a))
  29. X                     (nth 2 a))
  30. X                      (1+ tol)))))
  31. X    ((not (eq (car tol) 'float))
  32. X     (if (Math-realp tol)
  33. X         (math-to-fraction a (math-float tol))
  34. X       (math-reject-arg tol 'realp)))
  35. X    ((Math-negp tol)
  36. X     (math-to-fraction a (math-neg tol)))
  37. X    ((Math-zerop tol)
  38. X     (math-to-fraction a 0))
  39. X    ((not (math-lessp-float tol '(float 1 0)))
  40. X     (math-trunc a))
  41. X    ((Math-zerop a)
  42. X     0)
  43. X    (t
  44. X     (let ((cfrac (math-continued-fraction a tol))
  45. X           (calc-prefer-frac t))
  46. X       (math-eval-continued-fraction cfrac))))
  47. X)
  48. X(fset 'calcFunc-frac (symbol-function 'math-to-fraction))
  49. X
  50. X(defun math-continued-fraction (a tol)
  51. X  (let ((calc-internal-prec (+ calc-internal-prec 2)))
  52. X    (let ((cfrac nil)
  53. X      (aa a)
  54. X      (calc-prefer-frac nil)
  55. X      int)
  56. X      (while (or (null cfrac)
  57. X         (and (not (Math-zerop aa))
  58. X              (not (math-lessp-float
  59. X                (math-abs
  60. X                 (math-sub a
  61. X                       (let ((f (math-eval-continued-fraction
  62. X                         cfrac)))
  63. X                     (math-working "Fractionalize" f)
  64. X                     f)))
  65. X                tol))))
  66. X    (setq int (math-trunc aa)
  67. X          aa (math-sub aa int)
  68. X          cfrac (cons int cfrac))
  69. X    (or (Math-zerop aa)
  70. X        (setq aa (math-div 1 aa))))
  71. X      cfrac))
  72. X)
  73. X
  74. X(defun math-eval-continued-fraction (cf)
  75. X  (let ((n (car cf))
  76. X    (d 1)
  77. X    temp)
  78. X    (while (setq cf (cdr cf))
  79. X      (setq temp (math-add (math-mul (car cf) n) d)
  80. X        d n
  81. X        n temp))
  82. X    (math-div n d))
  83. X)
  84. X
  85. X
  86. X(defun math-clean-number (a &optional prec)   ; [X X S] [Public]
  87. X  (if prec
  88. X      (cond ((Math-messy-integerp prec)
  89. X         (math-clean-number a (math-trunc prec)))
  90. X        ((or (not (integerp prec))
  91. X         (< prec 3))
  92. X         (calc-record-why "Precision must be an integer 3 or above")
  93. X         (list 'calcFunc-clean a prec))
  94. X        ((not (Math-objvecp a))
  95. X         (list 'calcFunc-clean a prec))
  96. X        (t (let ((calc-internal-prec prec))
  97. X         (math-clean-number (math-normalize a)))))
  98. X    (cond ((eq (car-safe a) 'polar)
  99. X       (let ((theta (math-mod (nth 2 a)
  100. X                  (if (eq calc-angle-mode 'rad)
  101. X                      (math-two-pi)
  102. X                    360))))
  103. X         (math-neg
  104. X          (math-neg
  105. X           (math-normalize
  106. X        (list 'polar (nth 1 a) theta))))))
  107. X      ((Math-vectorp a)
  108. X       (math-map-vec 'math-clean-number a))
  109. X      ((Math-objectp a) a)
  110. X      (t (list 'calcFunc-clean a))))
  111. X)
  112. X(fset 'calcFunc-clean (symbol-function 'math-clean-number))
  113. X
  114. X
  115. X
  116. X
  117. X;;;; Logical operations.
  118. X
  119. X(defun calcFunc-eq (a b)
  120. X  (let ((res (math-compare a b)))
  121. X    (if (= res 0)
  122. X    1
  123. X      (if (= res 2)
  124. X      (list 'calcFunc-eq a b)
  125. X    0)))
  126. X)
  127. X
  128. X(defun calcFunc-neq (a b)
  129. X  (let ((res (math-compare a b)))
  130. X    (if (= res 0)
  131. X    0
  132. X      (if (= res 2)
  133. X      (list 'calcFunc-neq a b)
  134. X    1)))
  135. X)
  136. X
  137. X(defun calcFunc-lt (a b)
  138. X  (let ((res (math-compare a b)))
  139. X    (if (= res -1)
  140. X    1
  141. X      (if (= res 2)
  142. X      (list 'calcFunc-lt a b)
  143. X    0)))
  144. X)
  145. X
  146. X(defun calcFunc-gt (a b)
  147. X  (let ((res (math-compare a b)))
  148. X    (if (= res 1)
  149. X    1
  150. X      (if (= res 2)
  151. X      (list 'calcFunc-gt a b)
  152. X    0)))
  153. X)
  154. X
  155. X(defun calcFunc-leq (a b)
  156. X  (let ((res (math-compare a b)))
  157. X    (if (= res 1)
  158. X    0
  159. X      (if (= res 2)
  160. X      (list 'calcFunc-leq a b)
  161. X    1)))
  162. X)
  163. X
  164. X(defun calcFunc-geq (a b)
  165. X  (let ((res (math-compare a b)))
  166. X    (if (= res -1)
  167. X    0
  168. X      (if (= res 2)
  169. X      (list 'calcFunc-geq a b)
  170. X    1)))
  171. X)
  172. X
  173. X(defun calcFunc-land (a b)
  174. X  (cond ((Math-zerop a)
  175. X     a)
  176. X    ((Math-zerop b)
  177. X     b)
  178. X    ((Math-numberp a)
  179. X     b)
  180. X    ((Math-numberp b)
  181. X     a)
  182. X    (t (list 'calcFunc-land a b)))
  183. X)
  184. X
  185. X(defun calcFunc-lor (a b)
  186. X  (cond ((Math-zerop a)
  187. X     b)
  188. X    ((Math-zerop b)
  189. X     a)
  190. X    ((Math-numberp a)
  191. X     a)
  192. X    ((Math-numberp b)
  193. X     b)
  194. X    (t (list 'calcFunc-lor a b)))
  195. X)
  196. X
  197. X(defun calcFunc-lnot (a)
  198. X  (if (Math-zerop a)
  199. X      1
  200. X    (if (Math-numberp a)
  201. X    0
  202. X      (list 'calcFunc-lnot a)))
  203. X)
  204. X
  205. X(defun calcFunc-if (c e1 e2)
  206. X  (if (Math-zerop c)
  207. X      e2
  208. X    (if (Math-numberp c)
  209. X    e1
  210. X      (list 'calcFunc-if c e1 e2)))
  211. X)
  212. X
  213. X(defun math-normalize-logical-op (a)
  214. X  (or (and (eq (car a) 'calcFunc-if)
  215. X       (= (length a) 4)
  216. X       (let ((a1 (math-normalize (nth 1 a))))
  217. X         (if (Math-zerop a1)
  218. X         (math-normalize (nth 3 a))
  219. X           (if (Math-numberp a1)
  220. X           (math-normalize (nth 2 a))
  221. X         (list 'calcFunc-if a1 (nth 2 a) (nth 3 a))))))
  222. X      a)
  223. X)
  224. X
  225. X(defun calcFunc-in (a b)
  226. X  (or (and (eq (car-safe b) 'vec)
  227. X       (let ((bb b))
  228. X         (while (and (setq bb (cdr bb))
  229. X             (not (if (memq (car-safe (car bb)) '(vec intv))
  230. X                  (eq (calcFunc-in a (car bb)) 1)
  231. X                (math-equal a (car bb))))))
  232. X         (if bb 1 (and (math-constp a) (math-constp bb) 0))))
  233. X      (and (eq (car-safe b) 'intv)
  234. X       (let ((res (math-compare a (nth 2 b))))
  235. X         (cond ((= res -1)
  236. X            0)
  237. X           ((= res 0)
  238. X            (if (memq (nth 1 b) '(2 3)) 1 0))
  239. X           ((/= res 1)
  240. X            nil)
  241. X           ((= (setq res (math-compare a (nth 3 b))) 1)
  242. X            0)
  243. X           ((= res 0)
  244. X            (if (memq (nth 1 b) '(1 3)) 1 0))
  245. X           ((/= res -1)
  246. X            nil)
  247. X           (t 1))))
  248. X      (and (math-equal a b)
  249. X       1)
  250. X      (and (math-constp a) (math-constp b)
  251. X       0)
  252. X      (list 'calcFunc-in a b))
  253. X)
  254. X
  255. X(defun calcFunc-typeof (a)
  256. X  (cond ((Math-integerp a) 1)
  257. X    ((eq (car a) 'frac) 2)
  258. X    ((eq (car a) 'float) 3)
  259. X    ((eq (car a) 'hms) 4)
  260. X    ((eq (car a) 'cplx) 5)
  261. X    ((eq (car a) 'polar) 6)
  262. X    ((eq (car a) 'sdev) 7)
  263. X    ((eq (car a) 'intv) 8)
  264. X    ((eq (car a) 'mod) 9)
  265. X    ((eq (car a) 'var) 100)
  266. X    ((eq (car a) 'vec) (if (math-matrixp a) 102 101))
  267. X    (t (let ((func (assq (car a) '( ( + . calcFunc-add )
  268. X                    ( - . calcFunc-sub )
  269. X                    ( * . calcFunc-mul )
  270. X                    ( / . calcFunc-div )
  271. X                    ( ^ . calcFunc-pow )
  272. X                    ( % . calcFunc-mod )
  273. X                    ( neg . calcFunc-neg )
  274. X                    ( | . calcFunc-vconcat ) ))))
  275. X         (setq func (if func (cdr func) (car a)))
  276. X         (math-calcFunc-to-var func))))
  277. X)
  278. X
  279. X(defun calcFunc-integer (a)
  280. X  (if (Math-integerp a)
  281. X      1
  282. X    (if (Math-objvecp a)
  283. X    0
  284. X      (list 'calcFunc-integer a)))
  285. X)
  286. X
  287. X(defun calcFunc-real (a)
  288. X  (if (Math-realp a)
  289. X      1
  290. X    (if (Math-objvecp a)
  291. X    0
  292. X      (list 'calcFunc-real a)))
  293. X)
  294. X
  295. X(defun calcFunc-constant (a)
  296. X  (if (math-constp a)
  297. X      1
  298. X    (if (Math-objvecp a)
  299. X    0
  300. X      (list 'calcFunc-constant a)))
  301. X)
  302. X
  303. X(defun calcFunc-refers (a b)
  304. X  (if (math-expr-contains a b)
  305. X      1
  306. X    (if (eq (car-safe a) 'var)
  307. X    (list 'calcFunc-refers a b)
  308. X      0))
  309. X)
  310. X
  311. X
  312. X
  313. X
  314. X;;;; Complex numbers.
  315. X
  316. X(defun math-to-polar (a)   ; [C N] [Public]
  317. X  (cond ((Math-vectorp a)
  318. X     (math-map-vec 'math-to-polar a))
  319. X    ((Math-realp a) a)
  320. X    ((Math-numberp a)
  321. X     (math-normalize (math-polar a)))
  322. X    (t (list 'calcFunc-polar)))
  323. X)
  324. X(fset 'calcFunc-polar (symbol-function 'math-to-polar))
  325. X
  326. X(defun math-to-rectangular (a)   ; [N N] [Public]
  327. X  (cond ((Math-vectorp a)
  328. X     (math-map-vec 'math-to-rectangular a))
  329. X    ((Math-realp a) a)
  330. X    ((Math-numberp a)
  331. X     (math-normalize (math-complex a)))
  332. X    (t (list 'calcFunc-rect)))
  333. X)
  334. X(fset 'calcFunc-rect (symbol-function 'math-to-rectangular))
  335. X
  336. X;;; Compute the complex conjugate of A.  [O O] [Public]
  337. X(defun math-conj (a)
  338. X  (cond ((math-real-objectp a)
  339. X     a)
  340. X    ((eq (car a) 'cplx)
  341. X     (list 'cplx (nth 1 a) (math-neg (nth 2 a))))
  342. X    ((eq (car a) 'polar)
  343. X     (list 'polar (nth 1 a) (math-neg (nth 2 a))))
  344. X    ((eq (car a) 'vec)
  345. X     (math-map-vec 'math-conj a))
  346. X    ((eq (car a) 'calcFunc-conj)
  347. X     (nth 1 a))
  348. X    (t (calc-record-why 'numberp a)
  349. X       (list 'calcFunc-conj a)))
  350. X)
  351. X(fset 'calcFunc-conj (symbol-function 'math-conj))
  352. X
  353. X;;; Compute the absolute value squared of A.  [F N] [Public]
  354. X(defun math-abssqr (a)
  355. X  (cond ((Math-realp a)
  356. X     (math-sqr a))
  357. X    ((eq (car a) 'cplx)
  358. X     (math-add (math-sqr (nth 1 a)) (math-sqr (nth 2 a))))
  359. X    ((eq (car a) 'polar)
  360. X     (math-sqr (nth 1 a)))
  361. X    ((and (memq (car a) '(sdev intv)) (math-constp a))
  362. X     (math-sqr (math-abs a)))
  363. X    ((eq (car a) 'vec)
  364. X     (math-reduce-vec 'math-add (math-map-vec 'math-abssqr a)))
  365. X    (t (calc-record-why 'numvecp a)
  366. X       (list 'calcFunc-abssqr a)))
  367. X)
  368. X(fset 'calcFunc-abssqr (symbol-function 'math-abssqr))
  369. X
  370. X;;; Compute the complex argument of A.  [F N] [Public]
  371. X(defun math-cplx-arg (a)
  372. X  (cond ((Math-anglep a)
  373. X     (if (math-negp a) (math-half-circle nil) 0))
  374. X    ((eq (car-safe a) 'cplx)
  375. X     (math-arctan2 (nth 2 a) (nth 1 a)))
  376. X    ((eq (car-safe a) 'polar)
  377. X     (nth 2 a))
  378. X    ((eq (car a) 'vec)
  379. X     (math-map-vec 'math-cplx-arg a))
  380. X    (t (calc-record-why 'numvecp a)
  381. X       (list 'calcFunc-arg a)))
  382. X)
  383. X(fset 'calcFunc-arg (symbol-function 'math-cplx-arg))
  384. X
  385. X;;; Extract the real or complex part of a complex number.  [R N] [Public]
  386. X;;; Also extracts the real part of a modulo form.
  387. X(defun math-real-part (a)
  388. X  (cond ((memq (car-safe a) '(mod sdev))
  389. X     (nth 1 a))
  390. X    ((math-real-objectp a) a)
  391. X    ((eq (car a) 'cplx)
  392. X     (nth 1 a))
  393. X    ((eq (car a) 'polar)
  394. X     (math-mul (nth 1 a) (math-cos (nth 2 a))))
  395. X    ((eq (car a) 'vec)
  396. X     (math-map-vec 'math-real-part a))
  397. X    (t (calc-record-why 'numberp a)
  398. X       (list 'calcFunc-re a)))
  399. X)
  400. X(fset 'calcFunc-re (symbol-function 'math-real-part))
  401. X
  402. X(defun math-imag-part (a)
  403. X  (cond ((math-real-objectp a)
  404. X     (if (math-floatp a) '(float 0 0) 0))
  405. X    ((eq (car a) 'cplx)
  406. X     (nth 2 a))
  407. X    ((eq (car a) 'polar)
  408. X     (math-mul (nth 1 a) (math-sin (nth 2 a))))
  409. X    ((eq (car a) 'vec)
  410. X     (math-map-vec 'math-imag-part a))
  411. X    (t (calc-record-why 'numberp a)
  412. X       (list 'calcFunc-im a)))
  413. X)
  414. X(fset 'calcFunc-im (symbol-function 'math-imag-part))
  415. X
  416. X
  417. X
  418. X;;;; Transcendental functions.
  419. X
  420. X;;; All of these functions are defined on the complex plane.
  421. X;;; (Branch cuts, etc. follow Steele's Common Lisp book.)
  422. X
  423. X;;; Most functions increase calc-internal-prec by 2 digits, then round
  424. X;;; down afterward.  "-raw" functions use the current precision, require
  425. X;;; their arguments to be in float (or complex float) format, and always
  426. X;;; work in radians (where applicable).
  427. X
  428. X(defun math-to-radians (a)   ; [N N]
  429. X  (cond ((eq (car-safe a) 'hms)
  430. X     (math-from-hms a 'rad))
  431. X    ((memq calc-angle-mode '(deg hms))
  432. X     (math-mul a (math-pi-over-180)))
  433. X    (t a))
  434. X)
  435. X
  436. X(defun math-from-radians (a)   ; [N N]
  437. X  (cond ((eq calc-angle-mode 'deg)
  438. X     (if (math-constp a)
  439. X         (math-div a (math-pi-over-180))
  440. X       (list 'calcFunc-deg a)))
  441. X    ((eq calc-angle-mode 'hms)
  442. X     (math-to-hms a 'rad))
  443. X    (t a))
  444. X)
  445. X
  446. X(defun math-to-radians-2 (a)   ; [N N]
  447. X  (cond ((eq (car-safe a) 'hms)
  448. X     (math-from-hms a 'rad))
  449. X    ((memq calc-angle-mode '(deg hms))
  450. X     (if calc-symbolic-mode
  451. X         (math-div (math-mul a '(var pi var-pi)) 180)
  452. X       (math-mul a (math-pi-over-180))))
  453. X    (t a))
  454. X)
  455. X
  456. X(defun math-from-radians-2 (a)   ; [N N]
  457. X  (cond ((memq calc-angle-mode '(deg hms))
  458. X     (if calc-symbolic-mode
  459. X         (math-div (math-mul 180 a) '(var pi var-pi))
  460. X       (math-div a (math-pi-over-180))))
  461. X    (t a))
  462. X)
  463. X
  464. X
  465. X
  466. X;;; Sine, cosine, and tangent.
  467. X
  468. X(defun math-sin (x)   ; [N N] [Public]
  469. X  (cond ((Math-scalarp x)
  470. X     (math-with-extra-prec 2
  471. X       (math-sin-raw (math-to-radians (math-float x)))))
  472. X    ((eq (car x) 'sdev)
  473. X     (if (math-constp x)
  474. X         (math-with-extra-prec 2
  475. X           (let* ((xx (math-to-radians (math-float (nth 1 x))))
  476. X              (xs (math-to-radians (math-float (nth 2 x))))
  477. X              (sc (math-sin-cos-raw xx)))
  478. X         (math-make-sdev (car sc)
  479. X                 (math-mul xs (math-abs (cdr sc))))))
  480. X       (math-make-sdev (math-sin (nth 1 x))
  481. X               (math-mul (nth 2 x)
  482. X                     (math-abs (math-cos (nth 1 x)))))))
  483. X    ((and (eq (car x) 'intv) (math-constp x))
  484. X     (math-cos (math-sub x (math-quarter-circle nil))))
  485. X    (t (calc-record-why 'scalarp x)
  486. X       (list 'calcFunc-sin x)))
  487. X)
  488. X(fset 'calcFunc-sin (symbol-function 'math-sin))
  489. X
  490. X(defun math-cos (x)   ; [N N] [Public]
  491. X  (cond ((Math-scalarp x)
  492. X     (math-with-extra-prec 2
  493. X       (math-cos-raw (math-to-radians (math-float x)))))
  494. X    ((eq (car x) 'sdev)
  495. X     (if (math-constp x)
  496. X         (math-with-extra-prec 2
  497. X           (let* ((xx (math-to-radians (math-float (nth 1 x))))
  498. X              (xs (math-to-radians (math-float (nth 2 x))))
  499. X              (sc (math-sin-cos-raw xx)))
  500. X         (math-make-sdev (cdr sc)
  501. X                 (math-mul xs (math-abs (car sc))))))
  502. X       (math-make-sdev (math-cos (nth 1 x))
  503. X               (math-mul (nth 2 x)
  504. X                     (math-abs (math-sin (nth 1 x)))))))
  505. X    ((and (eq (car x) 'intv) (math-constp x))
  506. X     (math-with-extra-prec 2
  507. X       (let* ((xx (math-to-radians (math-float x)))
  508. X          (na (math-floor (math-div (nth 2 xx) (math-pi))))
  509. X          (nb (math-floor (math-div (nth 3 xx) (math-pi))))
  510. X          (span (math-sub nb na)))
  511. X         (if (memq span '(0 1))
  512. X         (let ((int (math-sort-intv (nth 1 x)
  513. X                        (math-cos-raw (nth 2 xx))
  514. X                        (math-cos-raw (nth 3 xx)))))
  515. X           (if (eq span 1)
  516. X               (if (math-evenp na)
  517. X               (math-make-intv (logior (nth 1 x) 2)
  518. X                       -1
  519. X                       (nth 3 int))
  520. X             (math-make-intv (logior (nth 1 x) 1)
  521. X                     (nth 2 int)
  522. X                     1))
  523. X             int))
  524. X           (list 'intv 3 -1 1)))))
  525. X    (t (calc-record-why 'scalarp x)
  526. X       (list 'calcFunc-cos x)))
  527. X)
  528. X(fset 'calcFunc-cos (symbol-function 'math-cos))
  529. X
  530. X(defun math-sin-cos (x)   ; [V N] [Public]
  531. X  (if (Math-scalarp x)
  532. X      (math-with-extra-prec 2
  533. X    (let ((sc (math-sin-cos-raw (math-to-radians (math-float x)))))
  534. X      (list 'vec (cdr sc) (car sc))))    ; the vector [cos, sin]
  535. X    (list 'vec (math-sin x) (math-cos x)))
  536. X)
  537. X(fset 'calcFunc-sincos (symbol-function 'math-sin-cos))
  538. X
  539. X(defun math-tan (x)   ; [N N] [Public]
  540. X  (cond ((Math-scalarp x)
  541. X     (math-with-extra-prec 2
  542. X       (math-tan-raw (math-to-radians (math-float x)))))
  543. X    ((eq (car x) 'sdev)
  544. X     (if (math-constp x)
  545. X         (math-with-extra-prec 2
  546. X           (let* ((xx (math-to-radians (math-float (nth 1 x))))
  547. X              (xs (math-to-radians (math-float (nth 2 x))))
  548. X              (sc (math-sin-cos-raw xx)))
  549. X         (if (math-zerop (cdr sc))
  550. X             (progn
  551. X               (calc-record-why "Division by zero")
  552. X               (list 'calcFunc-tan x))
  553. X           (math-make-sdev (math-div-float (car sc) (cdr sc))
  554. X                   (math-div-float xs (math-sqr (cdr sc)))))))
  555. X       (math-make-sdev (math-tan (nth 1 x))
  556. X               (math-div (nth 2 x)
  557. X                     (math-sqr (math-cos (nth 1 x)))))))
  558. X    ((and (eq (car x) 'intv) (math-constp x))
  559. X     (or (math-with-extra-prec 2
  560. X           (let* ((xx (math-to-radians (math-float x)))
  561. X              (na (math-floor (math-div (math-sub (nth 2 xx)
  562. X                              (math-pi-over-2))
  563. X                        (math-pi))))
  564. X              (nb (math-floor (math-div (math-sub (nth 3 xx)
  565. X                              (math-pi-over-2))
  566. X                        (math-pi)))))
  567. X         (and (equal na nb)
  568. X              (math-sort-intv (nth 1 x)
  569. X                      (math-tan-raw (nth 2 xx))
  570. X                      (math-tan-raw (nth 3 xx))))))
  571. X         (progn
  572. X           (calc-record-why "Infinite interval" x)
  573. X           (list 'calcFunc-tan x))))
  574. X    (t (calc-record-why 'scalarp x)
  575. X       (list 'calcFunc-tan x)))
  576. X)
  577. X(fset 'calcFunc-tan (symbol-function 'math-tan))
  578. X
  579. X(defun math-sin-raw (x)   ; [N N]
  580. X  (cond ((eq (car-safe x) 'cplx)
  581. X     (let* ((expx (math-exp-raw (nth 2 x)))
  582. X        (expmx (math-div-float '(float 1 0) expx))
  583. X        (sc (math-sin-cos-raw (nth 1 x))))
  584. X       (list 'cplx
  585. X         (math-mul-float (car sc)
  586. X                 (math-mul-float (math-sub expx expmx)
  587. X                         '(float 5 -1)))
  588. X         (math-mul-float (cdr sc)
  589. X                 (math-mul-float (math-add-float expx expmx)
  590. X                         '(float 5 -1))))))
  591. X    ((eq (car-safe x) 'polar)
  592. X     (math-polar (math-sin-raw (math-complex x))))
  593. X    ((Math-integer-negp (nth 1 x))
  594. X     (math-neg-float (math-sin-raw (math-neg-float x))))
  595. X    ((math-lessp-float '(float 7 0) x)  ; avoid inf loops due to roundoff
  596. X     (math-sin-raw (math-mod x (math-two-pi))))
  597. X    (t (math-sin-raw-2 x x)))
  598. X)
  599. X
  600. X(defun math-cos-raw (x)   ; [N N]
  601. X  (if (eq (car-safe x) 'polar)
  602. X      (math-polar (math-cos-raw (math-complex x)))
  603. X    (math-sin-raw (math-sub-float (math-pi-over-2) x)))
  604. X)
  605. X
  606. X;;; This could use a smarter method:  Reduce x as in math-sin-raw, then
  607. X;;;   compute either sin(x) or cos(x), whichever is smaller, and compute
  608. X;;;   the other using the identity sin(x)^2 + cos(x)^2 = 1.
  609. X(defun math-sin-cos-raw (x)   ; [F.F F]  (result is (sin x . cos x))
  610. X  (cons (math-sin-raw x) (math-cos-raw x))
  611. X)
  612. X
  613. X(defun math-tan-raw (x)   ; [N N]
  614. X  (cond ((eq (car-safe x) 'cplx)
  615. X     (let* ((x (math-mul-float x '(float 2 0)))
  616. X        (expx (math-exp-raw (nth 2 x)))
  617. X        (expmx (math-div-float '(float 1 0) expx))
  618. X        (sc (math-sin-cos-raw (nth 1 x)))
  619. X        (d (math-add-float (cdr sc)
  620. X                   (math-mul-float (math-add-float expx expmx)
  621. X                           '(float 5 -1)))))
  622. X       (and (not (eq (nth 1 d) 0))
  623. X        (list 'cplx
  624. X              (math-div-float (car sc) d)
  625. X              (math-div-float (math-mul-float (math-add expx expmx)
  626. X                              '(float 5 -1)) d)))))
  627. X    ((eq (car-safe x) 'polar)
  628. X     (math-polar (math-tan-raw (math-complex x))))
  629. X    (t
  630. X     (let ((sc (math-sin-cos-raw x)))
  631. X       (if (eq (nth 1 (cdr sc)) 0)
  632. X           (math-reject-arg x "Division by zero")
  633. X         (math-div-float (car sc) (cdr sc))))))
  634. X)
  635. X
  636. X(defun math-sin-raw-2 (x orgx)   ; This avoids poss of inf recursion.  [F F]
  637. X  (let ((xmpo2 (math-sub-float (math-pi-over-2) x)))
  638. X    (cond ((Math-integer-negp (nth 1 xmpo2))
  639. X       (math-neg-float (math-sin-raw-2 (math-sub-float x (math-pi))
  640. X                       orgx)))
  641. X      ((math-lessp-float (math-pi-over-4) x)
  642. X       (math-cos-raw-2 xmpo2 orgx))
  643. X      ((math-lessp-float x (math-neg (math-pi-over-4)))
  644. X       (math-neg (math-cos-raw-2 (math-add (math-pi-over-2) x) orgx)))
  645. X      ((math-nearly-zerop-float x orgx) '(float 0 0))
  646. X      (calc-symbolic-mode (signal 'inexact-result nil))
  647. X      (t (math-sin-series x 6 4 x (math-neg-float (math-sqr-float x))))))
  648. X)
  649. X
  650. X(defun math-cos-raw-2 (x orgx)   ; [F F]
  651. X  (cond ((math-nearly-zerop-float x orgx) '(float 1 0))
  652. X    (calc-symbolic-mode (signal 'inexact-result nil))
  653. X    (t (let ((xnegsqr (math-neg-float (math-sqr-float x))))
  654. X         (math-sin-series
  655. X          (math-add-float '(float 1 0)
  656. X                  (math-mul-float xnegsqr '(float 5 -1)))
  657. X          24 5 xnegsqr xnegsqr))))
  658. X)
  659. X
  660. X(defun math-sin-series (sum nfac n x xnegsqr)
  661. X  (math-working "sin" sum)
  662. X  (let* ((nextx (math-mul-float x xnegsqr))
  663. X     (nextsum (math-add-float sum (math-div-float nextx
  664. X                              (math-float nfac)))))
  665. X    (if (math-nearly-equal-float sum nextsum)
  666. X    sum
  667. X      (math-sin-series nextsum (math-mul nfac (* n (1+ n)))
  668. X               (+ n 2) nextx xnegsqr)))
  669. X)
  670. X
  671. X
  672. X;;; Inverse sine, cosine, tangent.
  673. X
  674. X(defun math-arcsin (x)   ; [N N] [Public]
  675. X  (cond ((Math-numberp x)
  676. X     (math-with-extra-prec 2
  677. X       (math-from-radians (math-arcsin-raw (math-float x)))))
  678. X    ((and (eq (car x) 'sdev)
  679. X          (or (not (math-constp (nth 1 x)))
  680. X          (not (Math-lessp 1 (math-abs (nth 1 x))))))
  681. X     (math-make-sdev (math-arcsin (nth 1 x))
  682. X             (math-from-radians
  683. X              (math-div (nth 2 x)
  684. X                    (math-sqrt
  685. X                     (math-sub 1 (math-sqr (nth 1 x))))))))
  686. X    ((and (eq (car x) 'intv) (math-constp x))
  687. X     (math-sort-intv (nth 1 x)
  688. X             (math-arcsin (nth 2 x))
  689. X             (math-arcsin (nth 3 x))))
  690. X    (t (calc-record-why 'numberp x)
  691. X       (list 'calcFunc-arcsin x)))
  692. X)
  693. X(fset 'calcFunc-arcsin (symbol-function 'math-arcsin))
  694. X
  695. X(defun math-arccos (x)   ; [N N] [Public]
  696. X  (cond ((Math-numberp x)
  697. X     (math-with-extra-prec 2
  698. X       (math-from-radians (math-arccos-raw (math-float x)))))
  699. X    ((and (eq (car x) 'sdev)
  700. X          (or (not (math-constp (nth 1 x)))
  701. X          (not (Math-lessp 1 (math-abs (nth 1 x))))))
  702. X     (math-make-sdev (math-arccos (nth 1 x))
  703. X             (math-from-radians
  704. X              (math-div (nth 2 x)
  705. X                    (math-sqrt
  706. X                     (math-sub 1 (math-sqr (nth 1 x))))))))
  707. X    ((and (eq (car x) 'intv) (math-constp x))
  708. X     (math-sort-intv (nth 1 x)
  709. X             (math-arccos (nth 2 x))
  710. X             (math-arccos (nth 3 x))))
  711. X    (t (calc-record-why 'numberp x)
  712. X       (list 'calcFunc-arccos x)))
  713. X)
  714. X(fset 'calcFunc-arccos (symbol-function 'math-arccos))
  715. X
  716. X(defun math-arctan (x)   ; [N N] [Public]
  717. X  (cond ((Math-numberp x)
  718. X     (math-with-extra-prec 2
  719. X       (math-from-radians (math-arctan-raw (math-float x)))))
  720. X    ((eq (car x) 'sdev)
  721. X     (math-make-sdev (math-arctan (nth 1 x))
  722. X             (math-from-radians
  723. X              (math-div (nth 2 x)
  724. X                    (math-add 1 (math-sqr (nth 1 x)))))))
  725. X    ((and (eq (car x) 'intv) (math-constp x))
  726. X     (math-sort-intv (nth 1 x)
  727. X             (math-arctan (nth 2 x))
  728. X             (math-arctan (nth 3 x))))
  729. X    (t (calc-record-why 'numberp x)
  730. X       (list 'calcFunc-arctan x)))
  731. X)
  732. X(fset 'calcFunc-arctan (symbol-function 'math-arctan))
  733. X
  734. X(defun math-arcsin-raw (x)   ; [N N]
  735. X  (let ((a (math-sqrt-raw (math-sub '(float 1 0) (math-sqr x)))))
  736. X    (if (or (memq (car-safe x) '(cplx polar))
  737. X        (memq (car-safe a) '(cplx polar)))
  738. X    (math-with-extra-prec 2   ; use extra precision for difficult case
  739. X      (math-mul '(cplx 0 -1)
  740. X            (math-ln-raw (math-add (math-mul '(cplx 0 1) x) a))))
  741. X      (math-arctan2-raw x a)))
  742. X)
  743. X
  744. X(defun math-arccos-raw (x)   ; [N N]
  745. X  (math-sub (math-pi-over-2) (math-arcsin-raw x))
  746. X)
  747. X
  748. X(defun math-arctan-raw (x)   ; [N N]
  749. X  (cond ((memq (car-safe x) '(cplx polar))
  750. X     (math-with-extra-prec 2   ; extra-extra
  751. X       (math-mul '(cplx 0 -1)
  752. X             (math-ln-raw (math-mul
  753. X                   (math-add 1 (math-mul '(cplx 0 1) x))
  754. X                   (math-sqrt-raw
  755. X                    (math-div 1 (math-add
  756. X                         1 (math-sqr x)))))))))
  757. X    ((Math-integer-negp (nth 1 x))
  758. X     (math-neg-float (math-arctan-raw (math-neg-float x))))
  759. X    ((math-zerop x) x)
  760. X    ((math-equal-int x 1) (math-pi-over-4))
  761. X    ((math-equal-int x -1) (math-neg (math-pi-over-4)))
  762. X    (calc-symbolic-mode (signal 'inexact-result nil))
  763. X    ((math-lessp-float '(float 414214 -6) x)  ; if x > sqrt(2) - 1, reduce
  764. X     (if (math-lessp-float '(float 1 0) x)
  765. X         (math-sub-float (math-mul-float (math-pi) '(float 5 -1))
  766. X                 (math-arctan-raw (math-div-float '(float 1 0) x)))
  767. X       (math-sub-float (math-mul-float (math-pi) '(float 25 -2))
  768. X               (math-arctan-raw (math-div-float
  769. X                         (math-sub-float '(float 1 0) x)
  770. X                         (math-add-float '(float 1 0)
  771. X                                 x))))))
  772. X    (t (math-arctan-series x 3 x (math-neg-float (math-sqr-float x)))))
  773. X)
  774. X
  775. X(defun math-arctan-series (sum n x xnegsqr)
  776. X  (math-working "arctan" sum)
  777. X  (let* ((nextx (math-mul-float x xnegsqr))
  778. X     (nextsum (math-add-float sum (math-div-float nextx (math-float n)))))
  779. X    (if (math-nearly-equal-float sum nextsum)
  780. X    sum
  781. X      (math-arctan-series nextsum (+ n 2) nextx xnegsqr)))
  782. X)
  783. X
  784. X(defun math-arctan2 (y x)   ; [F R R] [Public]
  785. X  (if (Math-anglep y)
  786. X      (if (Math-anglep x)
  787. X      (math-with-extra-prec 2
  788. X        (math-from-radians (math-arctan2-raw (math-float y)
  789. X                         (math-float x))))
  790. X    (calc-record-why 'anglep x)
  791. X    (list 'calcFunc-arctan2 y x))
  792. X    (calc-record-why 'anglep y)
  793. X    (list 'calcFunc-arctan2 y x))
  794. X)
  795. X(fset 'calcFunc-arctan2 (symbol-function 'math-arctan2))
  796. X
  797. X(defun math-arctan2-raw (y x)   ; [F R R]
  798. X  (cond ((math-zerop y)
  799. X     (if (math-negp x) (math-pi) 0))
  800. X    ((math-zerop x)
  801. X     (if (math-posp y)
  802. X         (math-pi-over-2)
  803. X       (math-neg (math-pi-over-2))))
  804. X    ((math-posp x)
  805. X     (math-arctan-raw (math-div-float y x)))
  806. X    ((math-posp y)
  807. X     (math-add-float (math-arctan-raw (math-div-float y x))
  808. X             (math-pi)))
  809. X    (t
  810. X     (math-sub-float (math-arctan-raw (math-div-float y x))
  811. X             (math-pi))))
  812. X)
  813. X
  814. X(defun math-arc-sin-cos (x)   ; [V N] [Public]
  815. X  (if (and (Math-vectorp x)
  816. X       (= (length x) 3))
  817. X      (math-arctan2 (nth 2 x) (nth 1 x))
  818. X    (math-reject-arg x "Two-element vector expected"))
  819. X)
  820. X(fset 'calcFunc-arcsincos (symbol-function 'math-arc-sin-cos))
  821. X
  822. X
  823. X
  824. X;;; Exponential function.
  825. X
  826. X(defun math-exp (x)   ; [N N] [Public]
  827. X  (cond ((Math-numberp x)
  828. X     (math-with-extra-prec 2 (math-exp-raw (math-float x))))
  829. X    ((eq (car-safe x) 'sdev)
  830. X     (let ((ex (math-exp (nth 1 x))))
  831. X       (math-make-sdev ex (math-mul (nth 2 x) ex))))
  832. X    ((eq (car-safe x) 'intv)
  833. X     (math-make-intv (nth 1 x) (math-exp (nth 2 x)) (math-exp (nth 3 x))))
  834. X    (t (calc-record-why 'numberp x)
  835. X       (list 'calcFunc-exp x)))
  836. X)
  837. X(fset 'calcFunc-exp (symbol-function 'math-exp))
  838. X
  839. X(defun math-exp-minus-1 (x)   ; [N N] [Public]
  840. X  (cond ((math-zerop x) '(float 0 0))
  841. X    (calc-symbolic-mode (signal 'inexact-result nil))
  842. X    ((Math-numberp x)
  843. X     (math-with-extra-prec 2
  844. X       (let ((x (math-float x)))
  845. X         (if (and (eq (car x) 'float)
  846. X              (math-lessp-float x '(float 1 0))
  847. X              (math-lessp-float '(float -1 0) x))
  848. X         (math-exp-minus-1-raw x)
  849. X           (math-add (math-exp-raw x) -1)))))
  850. X    ((eq (car-safe x) 'sdev)
  851. X     (if (math-constp x)
  852. X         (let ((ex (math-exp-minus-1 (nth 1 x))))
  853. X           (math-make-sdev ex (math-mul (nth 2 x) (math-add ex 1))))
  854. X       (math-make-sdev (math-exp-minus-1 (nth 1 x))
  855. X               (math-mul (nth 2 x) (math-exp (nth 1 x))))))
  856. X    ((eq (car-safe x) 'intv)
  857. X     (math-make-intv (nth 1 x)
  858. X             (math-exp-minus-1 (nth 2 x))
  859. X             (math-exp-minus-1 (nth 3 x))))
  860. X    (t (calc-record-why 'numberp x)
  861. X       (list 'calcFunc-expm1 x)))
  862. X)
  863. X(fset 'calcFunc-expm1 (symbol-function 'math-exp-minus-1))
  864. X
  865. X(defun math-exp10 (x)   ; [N N] [Public]
  866. X  (math-pow '(float 1 1) x)
  867. X)
  868. X(fset 'calcFunc-exp10 (symbol-function 'math-exp10))
  869. X
  870. X(defun math-exp-raw (x)   ; [N N]
  871. X  (cond ((math-zerop x) '(float 1 0))
  872. X    (calc-symbolic-mode (signal 'inexact-result nil))
  873. X    ((eq (car x) 'cplx)
  874. X     (let ((expx (math-exp-raw (nth 1 x)))
  875. X           (sc (math-sin-cos-raw (nth 2 x))))
  876. X       (list 'cplx
  877. X         (math-mul-float expx (cdr sc))
  878. X         (math-mul-float expx (car sc)))))
  879. X    ((eq (car x) 'polar)
  880. X     (let ((xc (math-complex x)))
  881. X       (list 'polar
  882. X         (math-exp-raw (nth 1 x))
  883. X         (nth 2 x))))
  884. X    ((or (math-lessp-float '(float 5 -1) x)
  885. X         (math-lessp-float x '(float -5 -1)))
  886. X     (let* ((two-x (math-mul-float x '(float 2 0)))
  887. X        (hint (math-scale-int (nth 1 two-x) (nth 2 two-x)))
  888. X        (hfrac (math-sub-float x (math-mul-float (math-float hint)
  889. X                             '(float 5 -1)))))
  890. X       (math-mul-float (math-ipow (math-sqrt-e) hint)
  891. X               (math-add-float '(float 1 0)
  892. X                       (math-exp-minus-1-raw hfrac)))))
  893. X    (t (math-add-float '(float 1 0) (math-exp-minus-1-raw x))))
  894. X)
  895. X
  896. X(defun math-exp-minus-1-raw (x)   ; [F F]
  897. X  (math-exp-series x 2 3 x x)
  898. X)
  899. X
  900. X(defun math-exp-series (sum nfac n xpow x)
  901. X  (math-working "exp" sum)
  902. X  (let* ((nextx (math-mul-float xpow x))
  903. X      (nextsum (math-add-float sum (math-div-float nextx
  904. X                               (math-float nfac)))))
  905. X     (if (math-nearly-equal-float sum nextsum)
  906. X     sum
  907. X       (math-exp-series nextsum (math-mul nfac n) (1+ n) nextx x)))
  908. X)
  909. X
  910. X
  911. X
  912. X;;; Logarithms.
  913. X
  914. X(defun math-ln (x)   ; [N N] [Public]
  915. X  (cond ((math-zerop x)
  916. X     (math-reject-arg x "Logarithm of zero"))
  917. X    ((Math-numberp x)
  918. X     (math-with-extra-prec 2 (math-ln-raw (math-float x))))
  919. X    ((and (eq (car-safe x) 'sdev)
  920. X          (or (not (math-constp (nth 1 x)))
  921. X          (math-posp (nth 1 x))))
  922. X     (math-make-sdev (math-ln (nth 1 x))
  923. X             (math-div (nth 2 x) (nth 1 x))))
  924. X    ((and (eq (car-safe x) 'intv) (Math-posp (nth 2 x)))
  925. X     (math-make-intv (nth 1 x) (math-ln (nth 2 x)) (math-ln (nth 3 x))))
  926. X    ((equal x '(var e var-e))
  927. X     1)
  928. X    ((and (eq (car-safe x) '^)
  929. X          (equal (nth 1 x) '(var e var-e)))
  930. X     (nth 2 x))
  931. X    (t (calc-record-why 'numberp x)
  932. X       (list 'calcFunc-ln x)))
  933. X)
  934. X(fset 'calcFunc-ln (symbol-function 'math-ln))
  935. X
  936. X(defun math-log10 (x)   ; [N N] [Public]
  937. X  (cond ((Math-numberp x)
  938. X     (math-with-extra-prec 2
  939. X       (let ((xf (math-float x)))
  940. X         (if (eq (nth 1 xf) 0)
  941. X         (math-reject-arg x "Logarithm of zero"))
  942. X         (if (Math-integer-posp (nth 1 xf))
  943. X         (if (eq (nth 1 xf) 1)    ; log10(1*10^n) = n
  944. X             (math-float (nth 2 xf))
  945. X           (let ((xdigs (1- (math-numdigs (nth 1 xf)))))
  946. X             (math-add-float
  947. X              (math-div-float (math-ln-raw-2
  948. X                       (list 'float (nth 1 xf) (- xdigs)))
  949. X                      (math-ln-10))
  950. X              (math-float (+ (nth 2 xf) xdigs)))))
  951. X           (math-div (math-ln xf) (math-ln-10))))))
  952. X    ((and (eq (car-safe x) 'sdev)
  953. X          (or (not (math-constp (nth 1 x)))
  954. X          (math-posp (nth 1 x))))
  955. X     (math-make-sdev (math-log10 (nth 1 x))
  956. X             (math-div (nth 2 x)
  957. X                   (math-mul (nth 1 x) (math-ln 10)))))
  958. X    ((and (eq (car-safe x) 'intv) (Math-posp (nth 2 x)))
  959. X     (math-make-intv (nth 1 x)
  960. X             (math-log10 (nth 2 x))
  961. X             (math-log10 (nth 3 x))))
  962. X    (t (calc-record-why 'numberp x)
  963. X       (list 'calcFunc-log10 x)))
  964. X)
  965. X(fset 'calcFunc-log10 (symbol-function 'math-log10))
  966. X
  967. X(defun calcFunc-pow10 (x)
  968. X  (math-pow '(float 1 1) x)
  969. X)
  970. X
  971. X(defun math-log (x b)   ; [N N N] [Public]
  972. X  (cond ((or (eq b 10) (equal b '(float 1 1)))
  973. X     (math-log10 x))
  974. X    ((math-zerop x)
  975. X     (math-reject-arg x "Logarithm of zero"))
  976. X    ((math-zerop b)
  977. X     (math-reject-arg b "Logarithm of zero"))
  978. X    ((and (Math-numberp x) (Math-numberp b))
  979. X     (math-with-extra-prec 2
  980. X       (math-div (math-ln-raw (math-float x))
  981. X             (math-log-base-raw b))))
  982. X    ((and (eq (car-safe x) 'sdev)
  983. X          (or (not (math-constp (nth 1 x)))
  984. X          (math-posp (nth 1 x)))
  985. X          (Math-numberp b))
  986. X     (math-make-sdev (math-log (nth 1 x) b)
  987. X             (math-div (nth 2 x)
  988. X                   (math-mul (nth 1 x)
  989. X                         (math-log-base-raw b)))))
  990. X    ((and (eq (car-safe x) 'intv) (Math-posp (nth 2 x)))
  991. X     (math-make-intv (nth 1 x)
  992. X             (math-log (nth 2 x) b)
  993. X             (math-log (nth 3 x) b)))
  994. X    (t (if (Math-numberp b)
  995. X           (calc-record-why 'numberp x)
  996. X         (calc-record-why 'numberp b))
  997. X       (list 'calcFunc-log x b)))
  998. X)
  999. X
  1000. X(defun calcFunc-log (x &optional b)
  1001. X  (if b
  1002. X      (if (or (eq b 10) (equal b '(float 1 1)))
  1003. X      (math-normalize (list 'calcFunc-log10 x))
  1004. X    (if (equal b '(var e var-e))
  1005. X        (math-normalize (list 'calcFunc-ln x))
  1006. X      (math-log x b)))
  1007. X    (math-normalize (list 'calcFunc-ln x)))
  1008. X)
  1009. X(defun calcFunc-ilog (x &optional b)
  1010. X  (if b
  1011. X      (if (equal b '(var e var-e))
  1012. X      (math-normalize (list 'calcFunc-exp x))
  1013. X    (math-pow b x))
  1014. X    (math-normalize (list 'calcFunc-exp x)))
  1015. X)
  1016. X
  1017. X
  1018. X(defun math-log-base-raw (b)   ; [N N]
  1019. X  (if (not (and (equal (car math-log-base-cache) b)
  1020. X        (eq (nth 1 math-log-base-cache) calc-internal-prec)))
  1021. X      (setq math-log-base-cache (list b calc-internal-prec
  1022. X                      (math-ln-raw (math-float b)))))
  1023. X  (nth 2 math-log-base-cache)
  1024. X)
  1025. X(setq math-log-base-cache nil)
  1026. X
  1027. X(defun math-ln-plus-1 (x)   ; [N N] [Public]
  1028. X  (cond ((Math-equal-int x -1) (math-reject-arg x "Logarithm of zero"))
  1029. X    ((math-zerop x) '(float 0 0))
  1030. X    (calc-symbolic-mode (signal 'inexact-result nil))
  1031. X    ((Math-numberp x)
  1032. X     (math-with-extra-prec 2
  1033. X       (let ((x (math-float x)))
  1034. X         (if (and (eq (car x) 'float)
  1035. X              (math-lessp-float x '(float 5 -1))
  1036. X              (math-lessp-float '(float -5 -1) x))
  1037. X         (math-ln-plus-1-raw x)
  1038. X           (math-ln-raw (math-add-float x '(float 1 0)))))))
  1039. X    ((and (eq (car-safe x) 'sdev)
  1040. X          (or (not (math-constp (nth 1 x)))
  1041. X          (Math-lessp -1 (nth 1 x))))
  1042. X     (math-make-sdev (math-ln-plus-1 (nth 1 x))
  1043. X             (math-div (nth 2 x) (math-add (nth 1 x) 1))))
  1044. X    ((and (eq (car-safe x) 'intv) (Math-posp (nth 2 x)))
  1045. X     (math-make-intv (nth 1 x)
  1046. X             (math-ln-plus-1 (nth 2 x))
  1047. X             (math-ln-plus-1 (nth 3 x))))
  1048. X    (t (calc-record-why 'numberp x)
  1049. X       (list 'calcFunc-lnp1 x)))
  1050. X)
  1051. X(fset 'calcFunc-lnp1 (symbol-function 'math-ln-plus-1))
  1052. X
  1053. X(defun math-ln-raw (x)    ; [N N] --- must be float format!
  1054. X  (cond ((eq (car-safe x) 'cplx)
  1055. X     (list 'cplx
  1056. X           (math-mul-float (math-ln-raw
  1057. X                (math-add-float (math-sqr-float (nth 1 x))
  1058. X                        (math-sqr-float (nth 2 x))))
  1059. X                   '(float 5 -1))
  1060. X           (math-arctan2-raw (nth 2 x) (nth 1 x))))
  1061. X    ((eq (car x) 'polar)
  1062. X     (math-polar (list 'cplx
  1063. X               (math-ln-raw (nth 1 x))
  1064. X               (nth 2 x))))
  1065. X    ((Math-equal-int x 1)
  1066. X     '(float 0 0))
  1067. X    (calc-symbolic-mode (signal 'inexact-result nil))
  1068. X    ((math-posp (nth 1 x))    ; positive and real
  1069. X     (let ((xdigs (1- (math-numdigs (nth 1 x)))))
  1070. X       (math-add-float (math-ln-raw-2 (list 'float (nth 1 x) (- xdigs)))
  1071. X               (math-mul-float (math-float (+ (nth 2 x) xdigs))
  1072. X                       (math-ln-10)))))
  1073. X    ((math-zerop x)
  1074. X     (error "Logarithm of zero"))
  1075. X    ((eq calc-complex-mode 'polar)    ; negative and real
  1076. X     (math-polar
  1077. X      (list 'cplx   ; negative and real
  1078. X        (math-ln-raw (math-neg-float x))
  1079. X        (math-pi))))
  1080. X    (t (list 'cplx   ; negative and real
  1081. X         (math-ln-raw (math-neg-float x))
  1082. X         (math-pi))))
  1083. X)
  1084. X
  1085. X(defun math-ln-raw-2 (x)    ; [F F]
  1086. X  (cond ((math-lessp-float '(float 14 -1) x)
  1087. X     (math-add-float (math-ln-raw-2 (math-mul-float x '(float 5 -1)))
  1088. X             (math-ln-2)))
  1089. X    (t    ; now .7 < x <= 1.4
  1090. X     (math-ln-raw-3 (math-div-float (math-sub-float x '(float 1 0))
  1091. X                    (math-add-float x '(float 1 0))))))
  1092. X)
  1093. X
  1094. X(defun math-ln-raw-3 (x)   ; [F F]
  1095. X  (math-mul-float (math-ln-raw-series x 3 x (math-sqr-float x))
  1096. X          '(float 2 0))
  1097. X)
  1098. X
  1099. X;;; Compute ln((1+x)/(1-x))
  1100. X(defun math-ln-raw-series (sum n x xsqr)
  1101. X  (math-working "log" sum)
  1102. X  (let* ((nextx (math-mul-float x xsqr))
  1103. X     (nextsum (math-add-float sum (math-div-float nextx (math-float n)))))
  1104. X    (if (math-nearly-equal-float sum nextsum)
  1105. X    sum
  1106. X      (math-ln-raw-series nextsum (+ n 2) nextx xsqr)))
  1107. X)
  1108. X
  1109. X(defun math-ln-plus-1-raw (x)
  1110. X  (math-lnp1-series x 2 x (math-neg x))
  1111. X)
  1112. X
  1113. X(defun math-lnp1-series (sum n xpow x)
  1114. X  (math-working "lnp1" sum)
  1115. X  (let* ((nextx (math-mul-float xpow x))
  1116. X     (nextsum (math-add-float sum (math-div-float nextx (math-float n)))))
  1117. X    (if (math-nearly-equal-float sum nextsum)
  1118. X    sum
  1119. X      (math-lnp1-series nextsum (1+ n) nextx x)))
  1120. X)
  1121. X
  1122. X(math-defcache math-ln-10 (float (bigpos 018 684 045 994 092 585 302 2) -21)
  1123. X  (math-ln-raw-2 '(float 1 1)))
  1124. X
  1125. X(math-defcache math-ln-2 (float (bigpos 417 309 945 559 180 147 693) -21)
  1126. X  (math-ln-raw-3 (math-float '(frac 1 3))))
  1127. X
  1128. X
  1129. X
  1130. X;;; Hyperbolic functions.
  1131. X
  1132. X(defun math-sinh (x)   ; [N N] [Public]
  1133. X  (cond ((Math-numberp x)
  1134. X     (math-with-extra-prec 2
  1135. X       (let ((expx (math-exp-raw (math-float x))))
  1136. X         (math-mul (math-add expx (math-div -1 expx)) '(float 5 -1)))))
  1137. X    ((eq (car-safe x) 'sdev)
  1138. X     (math-make-sdev (math-sinh (nth 1 x))
  1139. X             (math-mul (nth 2 x) (math-cosh (nth 1 x)))))
  1140. X    ((and (eq (car x) 'intv) (math-constp x))
  1141. X     (math-sort-intv (nth 1 x)
  1142. X             (math-sinh (nth 2 x))
  1143. X             (math-sinh (nth 3 x))))
  1144. X    (t (calc-record-why 'numberp x)
  1145. X       (list 'calcFunc-sinh x)))
  1146. X)
  1147. X(fset 'calcFunc-sinh (symbol-function 'math-sinh))
  1148. X
  1149. X(defun math-cosh (x)   ; [N N] [Public]
  1150. X  (cond ((Math-numberp x)
  1151. X     (math-with-extra-prec 2
  1152. X       (let ((expx (math-exp-raw (math-float x))))
  1153. X         (math-mul (math-add expx (math-div 1 expx)) '(float 5 -1)))))
  1154. X    ((eq (car-safe x) 'sdev)
  1155. X     (math-make-sdev (math-cosh (nth 1 x))
  1156. X             (math-mul (nth 2 x)
  1157. X                   (math-abs (math-sinh (nth 1 x))))))
  1158. X    ((and (eq (car x) 'intv) (math-constp x))
  1159. X     (setq x (math-abs x))
  1160. X     (math-sort-intv (nth 1 x)
  1161. X             (math-cosh (nth 2 x))
  1162. X             (math-cosh (nth 3 x))))
  1163. X    (t (calc-record-why 'numberp x)
  1164. X       (list 'calcFunc-cosh x)))
  1165. X)
  1166. X(fset 'calcFunc-cosh (symbol-function 'math-cosh))
  1167. X
  1168. X(defun math-tanh (x)   ; [N N] [Public]
  1169. X  (cond ((Math-numberp x)
  1170. X     (math-with-extra-prec 2
  1171. X       (let* ((expx (math-exp (math-float x)))
  1172. X          (expmx (math-div 1 expx)))
  1173. X         (math-div (math-sub expx expmx)
  1174. X               (math-add expx expmx)))))
  1175. X    ((eq (car-safe x) 'sdev)
  1176. X     (math-make-sdev (math-tanh (nth 1 x))
  1177. X             (math-div (nth 2 x)
  1178. X                   (math-sqr (math-cosh (nth 1 x))))))
  1179. X    ((and (eq (car x) 'intv) (math-constp x))
  1180. X     (math-sort-intv (nth 1 x)
  1181. X             (math-tanh (nth 2 x))
  1182. X             (math-tanh (nth 3 x))))
  1183. X    (t (calc-record-why 'numberp x)
  1184. X       (list 'calcFunc-tanh x)))
  1185. X)
  1186. X(fset 'calcFunc-tanh (symbol-function 'math-tanh))
  1187. X
  1188. X(defun math-arcsinh (x)   ; [N N] [Public]
  1189. X  (cond ((Math-numberp x)
  1190. X     (math-with-extra-prec 2
  1191. X       (math-ln-raw (math-add x (math-sqrt-raw (math-add (math-sqr x)
  1192. X                                 '(float 1 0)))))))
  1193. X    ((eq (car-safe x) 'sdev)
  1194. X     (math-make-sdev (math-arcsinh (nth 1 x))
  1195. X             (math-div (nth 2 x)
  1196. X                   (math-sqrt
  1197. X                    (math-add (math-sqr (nth 1 x)) 1)))))
  1198. X    ((and (eq (car x) 'intv) (math-constp x))
  1199. X     (math-sort-intv (nth 1 x)
  1200. X             (math-arcsinh (nth 2 x))
  1201. X             (math-arcsinh (nth 3 x))))
  1202. X    (t (calc-record-why 'numberp x)
  1203. X       (list 'calcFunc-arcsinh x)))
  1204. X)
  1205. X(fset 'calcFunc-arcsinh (symbol-function 'math-arcsinh))
  1206. X
  1207. X(defun math-arccosh (x)   ; [N N] [Public]
  1208. X  (cond ((Math-numberp x)
  1209. X     (math-with-extra-prec 2
  1210. X       (if (or t    ; need to do this even in the real case!
  1211. X           (memq (car-safe x) '(cplx polar)))
  1212. X           (let ((xp1 (math-add 1 x)))    ; this gets the branch cuts right
  1213. X         (math-ln-raw
  1214. X          (math-add x (math-mul xp1
  1215. X                    (math-sqrt-raw (math-div (math-sub
  1216. X                                  x
  1217. X                                  '(float 1 0))
  1218. X                                 xp1))))))
  1219. X         (math-ln-raw
  1220. X          (math-add x (math-sqrt-raw (math-add (math-sqr x)
  1221. X                           '(float -1 0))))))))
  1222. X    ((and (eq (car-safe x) 'sdev)
  1223. X          (or (not (math-constp (nth 1 x)))
  1224. X          (not (Math-lessp (nth 1 x) 1))))
  1225. X     (math-make-sdev (math-arccosh (nth 1 x))
  1226. X             (math-div (nth 2 x)
  1227. X                   (math-sqrt
  1228. X                    (math-add (math-sqr (nth 1 x)) -1)))))
  1229. X    ((and (eq (car x) 'intv) (math-constp x))
  1230. X     (math-sort-intv (nth 1 x)
  1231. X             (math-arccosh (nth 2 x))
  1232. X             (math-arccosh (nth 3 x))))
  1233. X    (t (calc-record-why 'numberp x)
  1234. X       (list 'calcFunc-arccosh x)))
  1235. X)
  1236. X(fset 'calcFunc-arccosh (symbol-function 'math-arccosh))
  1237. X
  1238. X(defun math-arctanh (x)   ; [N N] [Public]
  1239. X  (cond ((Math-numberp x)
  1240. X     (math-with-extra-prec 2
  1241. X       (if (memq (car-safe x) '(cplx polar))
  1242. X           (math-ln-raw
  1243. X        (math-mul (math-add 1 x)
  1244. X              (math-sqrt-raw
  1245. X               (math-div '(float 1 0) (math-sub 1 (math-sqr x))))))
  1246. X         (math-mul (math-ln-raw (math-div (math-add '(float 1 0) x)
  1247. X                          (math-sub 1 x)))
  1248. X               '(float 5 -1)))))
  1249. X    ((and (eq (car-safe x) 'sdev)
  1250. X          (or (not (math-constp (nth 1 x)))
  1251. X          (Math-lessp (math-abs (nth 1 x)) 1)))
  1252. X     (math-make-sdev (math-arctanh (nth 1 x))
  1253. X             (math-div (nth 2 x)
  1254. X                   (math-sub 1 (math-sqr (nth 1 x))))))
  1255. X    ((and (eq (car x) 'intv) (math-constp x))
  1256. X     (math-sort-intv (nth 1 x)
  1257. X             (math-arctanh (nth 2 x))
  1258. X             (math-arctanh (nth 3 x))))
  1259. X    (t (calc-record-why 'numberp x)
  1260. X       (list 'calcFunc-arctanh x)))
  1261. X)
  1262. X(fset 'calcFunc-arctanh (symbol-function 'math-arctanh))
  1263. X
  1264. X
  1265. X;;; Convert A from HMS or degrees to radians.
  1266. X(defun math-deg-to-rad (a)   ; [R R] [Public]
  1267. X  (cond ((or (Math-numberp a)
  1268. X         (eq (car a) 'intv))
  1269. X     (math-mul a (math-pi-over-180)))
  1270. X    ((eq (car a) 'hms)
  1271. X     (math-from-hms a 'rad))
  1272. X    ((eq (car a) 'sdev)
  1273. X     (math-make-sdev (math-deg-to-rad (nth 1 a))
  1274. X             (math-deg-to-rad (nth 2 a))))
  1275. X    (t (list 'calcFunc-rad a)))
  1276. X)
  1277. X(fset 'calcFunc-rad (symbol-function 'math-deg-to-rad))
  1278. X
  1279. X;;; Convert A from HMS or radians to degrees.
  1280. X(defun math-rad-to-deg (a)   ; [R R] [Public]
  1281. X  (cond ((or (Math-numberp a)
  1282. X         (eq (car a) 'intv))
  1283. X     (math-div a (math-pi-over-180)))
  1284. X    ((eq (car a) 'hms)
  1285. X     (math-from-hms a 'deg))
  1286. X    ((eq (car a) 'sdev)
  1287. X     (math-make-sdev (math-rad-to-deg (nth 1 a))
  1288. X             (math-rad-to-deg (nth 2 a))))
  1289. X    (t (list 'calcFunc-deg a)))
  1290. X)
  1291. X(fset 'calcFunc-deg (symbol-function 'math-rad-to-deg))
  1292. X
  1293. X
  1294. X
  1295. X
  1296. X;;;; Number theory.
  1297. X
  1298. X(defun calcFunc-idiv (a b)   ; [I I I] [Public]
  1299. X  (cond ((and (Math-natnump a) (Math-natnump b) (not (eq b 0)))
  1300. X     (math-quotient a b))
  1301. X    ((Math-realp a)
  1302. X     (if (Math-realp b)
  1303. X         (let ((calc-prefer-frac t))
  1304. X           (math-floor (math-div a b)))
  1305. X       (math-reject-arg b 'realp)))
  1306. X    ((eq (car-safe a) 'hms)
  1307. X     (if (eq (car-safe b) 'hms)
  1308. X         (let ((calc-prefer-frac t))
  1309. X           (math-floor (math-div a b)))
  1310. X       (math-reject-arg b 'hmsp)))
  1311. X    ((and (or (eq (car-safe a) 'intv) (Math-realp a))
  1312. X          (or (eq (car-safe b) 'intv) (Math-realp b)))
  1313. X     (math-floor (math-div a b)))
  1314. X    (t (math-reject-arg a 'anglep)))
  1315. X)
  1316. X
  1317. X(defun calcFunc-fdiv (a b)   ; [R I I] [Public]
  1318. X  (if (Math-num-integerp a)
  1319. X      (if (Math-num-integerp b)
  1320. X      (if (Math-zerop b)
  1321. X          (math-reject-arg a "Division by zero")
  1322. X        (math-make-frac (math-trunc a) (math-trunc b)))
  1323. X    (math-reject-arg b 'integerp))
  1324. X    (math-reject-arg a 'integerp))
  1325. X)
  1326. X
  1327. X(defun math-lcm (a b)
  1328. X  (let ((g (math-gcd a b)))
  1329. X    (if (Math-numberp g)
  1330. X    (math-div (math-mul a b) g)
  1331. X      (list 'calcFunc-lcm a b)))
  1332. X)
  1333. X(fset 'calcFunc-lcm (symbol-function 'math-lcm))
  1334. X
  1335. X(defun math-extended-gcd (a b)   ; Knuth section 4.5.2
  1336. X  (cond
  1337. X   ((not (Math-integerp a))
  1338. X    (if (Math-messy-integerp a)
  1339. X    (math-extended-gcd (math-trunc a) b)
  1340. X      (calc-record-why 'integerp a)
  1341. X      (list 'calcFunc-egcd a b)))
  1342. X   ((not (Math-integerp b))
  1343. X    (if (Math-messy-integerp b)
  1344. X    (math-extended-gcd a (math-trunc b))
  1345. X      (calc-record-why 'integerp b)
  1346. X      (list 'calcFunc-egcd a b)))
  1347. X   (t
  1348. X    (let ((u1 1) (u2 0) (u3 a)
  1349. X      (v1 0) (v2 1) (v3 b)
  1350. X      t1 t2 q)
  1351. X      (while (not (eq v3 0))
  1352. X    (setq q (math-idivmod u3 v3)
  1353. X          t1 (math-sub u1 (math-mul v1 (car q)))
  1354. X          t2 (math-sub u2 (math-mul v2 (car q)))
  1355. X          u1 v1  u2 v2  u3 v3
  1356. X          v1 t1  v2 t2  v3 (cdr q)))
  1357. X      (list 'vec u3 u1 u2))))
  1358. X)
  1359. X(fset 'calcFunc-egcd (symbol-function 'math-extended-gcd))
  1360. X
  1361. X
  1362. X;;; Factorial and related functions.
  1363. X
  1364. X(defun math-factorial (n)   ; [I I] [F F] [Public]
  1365. X  (let (temp)
  1366. X    (cond ((Math-integer-negp n) (list 'calcFunc-fact n))
  1367. X      ((Math-zerop n) 1)
  1368. X      ((integerp n) (math-factorial-iter (1- n) 2 1))
  1369. X      ((and (math-messy-integerp n)
  1370. X        (Math-lessp (setq temp (math-trunc n)) 100))
  1371. X       (if (natnump temp)
  1372. X           (math-with-extra-prec 1
  1373. X         (math-factorial-iter (1- temp) 2 '(float 1 0)))
  1374. X         (list 'calcFunc-fact max)))
  1375. X      ((math-realp n)
  1376. X       (math-with-extra-prec 3
  1377. X         (math-gammap1-raw (math-float n))))
  1378. X      (t (calc-record-why 'realp n)
  1379. X         (list 'calcFunc-fact n))))
  1380. X)
  1381. X(fset 'calcFunc-fact (symbol-function 'math-factorial))
  1382. X
  1383. X(defun math-factorial-iter (count n f)
  1384. X  (if (= (% n 5) 1)
  1385. X      (math-working (format "factorial(%d)" (1- n)) f))
  1386. X  (if (> count 0)
  1387. X      (math-factorial-iter (1- count) (1+ n) (math-mul n f))
  1388. X    f)
  1389. X)
  1390. X
  1391. X(math-defcache math-sqrt-two-pi nil
  1392. X  (math-sqrt (math-two-pi)))
  1393. X
  1394. X(defun math-gammap1-raw (x)   ; compute gamma(1 + x)
  1395. X  (cond ((math-lessp-float x '(float 1 1))
  1396. X     (if (math-lessp-float x '(float -10 0))
  1397. X         (setq x (math-neg-float
  1398. X              (math-div-float
  1399. X               (math-pi)
  1400. X               (math-mul-float (math-gammap1-raw
  1401. X                    (math-add-float (math-neg-float x)
  1402. X                            '(float -1 0)))
  1403. X                       (math-sin-raw
  1404. X                    (math-mul (math-pi) x)))))))
  1405. X     (let ((xplus1 (math-add-float x '(float 1 0))))
  1406. X       (math-div-float (math-gammap1-raw xplus1) xplus1)))
  1407. X    (t   ; x now >= 10.0
  1408. X     (let ((xinv (math-div 1 x))
  1409. X           (lnx (math-ln-raw x)))
  1410. X       (math-mul (math-sqrt-two-pi)
  1411. X             (math-exp-raw
  1412. X              (math-gamma-series
  1413. X               (math-sub (math-mul (math-add x '(float 5 -1))
  1414. X                       lnx)
  1415. X                 x)
  1416. X               xinv
  1417. X               (math-sqr xinv)
  1418. X               2))))))
  1419. X)
  1420. X
  1421. X(defun calcFunc-gamma (x)
  1422. X  (calcFunc-fact (math-add x -1))
  1423. X)
  1424. X
  1425. X(defun math-gamma-series (sum x xinvsqr n)
  1426. X  (math-working "gamma" sum)
  1427. X  (let* ((bn (math-bernoulli-number n))   ; this will always be a "frac" form.
  1428. X     (next (math-add-float
  1429. X        sum
  1430. X        (math-mul-float (math-div-float (math-float (nth 1 bn))
  1431. X                        (math-float (* (nth 2 bn)
  1432. X                                   (* n (1- n)))))
  1433. X                x))))
  1434. X    (if (math-nearly-equal-float sum next)
  1435. X    next
  1436. X      (if (= n 24)
  1437. X      (progn
  1438. X        (calc-record-why "Gamma computation stopped early, not all digits may be valid")
  1439. X        next)
  1440. X    (math-gamma-series next (math-mul-float x xinvsqr) xinvsqr (+ n 2)))))
  1441. X)
  1442. X
  1443. X(defun math-bernoulli-number (n)
  1444. X  (if (= n 1)
  1445. X      '(frac -1 2)
  1446. X    (if (= (% n 2) 1)
  1447. X    0
  1448. X      (aref '[ 1 (frac 1 6) (frac -1 30) (frac 1 42) (frac -1 30)
  1449. X           (frac 5 66) (frac -691 2730) (frac 7 6) (frac -3617 510)
  1450. X           (frac 43867 798) (frac -174611 330) (frac 854513 138)
  1451. X           (frac (bigneg 91 364 236) 2730) ]
  1452. X        (/ n 2))))
  1453. X)
  1454. X;;; To come up with more, we could use this rule:
  1455. X;;;   Bn = n! bn
  1456. X;;;   bn = - sum_k=0^n-1 bk / (n-k+1)!
  1457. X
  1458. X(defun math-double-factorial (n)   ; [I I] [F F] [Public]
  1459. X  (cond ((Math-integer-negp n) (list 'calcFunc-dfact n))
  1460. X    ((Math-zerop n) 1)
  1461. X    ((integerp n) (math-double-factorial-iter n (+ 2 (% n 2)) 1))
  1462. X    ((math-messy-integerp n)
  1463. X     (let ((temp (math-trunc n)))
  1464. X       (if (natnump temp)
  1465. X           (math-with-extra-prec 1
  1466. X         (math-double-factorial-iter temp (+ 2 (% temp 2))
  1467. X                         '(float 1 0)))
  1468. X         (list 'calcFunc-dfact max))))
  1469. X    (t (calc-record-why 'natnump n)
  1470. X       (list 'calcFunc-dfact n)))
  1471. X)
  1472. X(fset 'calcFunc-dfact (symbol-function 'math-double-factorial))
  1473. X
  1474. X(defun math-double-factorial-iter (max n f)
  1475. X  (if (< (% n 10) 2)
  1476. X      (math-working (format "dfact(%d)" (- n 2)) f))
  1477. X  (if (<= n max)
  1478. X      (math-double-factorial-iter max (+ n 2) (math-mul n f))
  1479. X    f)
  1480. X)
  1481. X
  1482. X(defun math-permutations (n m)   ; [I I I] [F F F] [Public]
  1483. X  (cond ((and (integerp n) (integerp m) (<= m n) (>= m 0))
  1484. X     (math-factorial-iter n (1+ (- n m)) 1))
  1485. X    ((or (not (math-num-integerp n))
  1486. X         (not (math-num-integerp m)))
  1487. X     (or (math-realp n) (math-reject-arg n 'realp))
  1488. X     (or (math-realp m) (math-reject-arg m 'realp))
  1489. X     (and (math-num-integerp n) (math-negp n) (math-reject-arg n 'range))
  1490. X     (and (math-num-integerp m) (math-negp m) (math-reject-arg m 'range))
  1491. X     (math-div (math-factorial n) (math-factorial m)))
  1492. X    (t
  1493. X     (let ((tn (math-trunc n))
  1494. X           (tm (math-trunc m)))
  1495. X       (or (integerp tn) (math-reject-arg tn 'fixnump))
  1496. X       (or (integerp tm) (math-reject-arg tm 'fixnump))
  1497. X       (or (and (<= tm tn) (>= tm 0)) (math-reject-arg tm 'range))
  1498. X       (math-with-extra-prec 1
  1499. X         (math-factorial-iter tm (1+ (- tn tm)) '(float 1 0))))))
  1500. X)
  1501. X(fset 'calcFunc-perm (symbol-function 'math-permutations))
  1502. X
  1503. X(defun math-choose (n m)   ; [I I I] [F F F] [Public]
  1504. X  (cond ((and (integerp n) (integerp m) (<= m n) (>= m 0))
  1505. X     (math-choose-iter m n 1 1))
  1506. X    ((not (math-realp n))
  1507. X     (math-reject-arg n 'realp))
  1508. X    ((not (math-realp m))
  1509. X     (math-reject-arg m 'realp))
  1510. X    ((not (math-num-integerp m))
  1511. X     (if (and (math-num-integerp n) (math-negp n))
  1512. X         (list 'calcFunc-choose n m)
  1513. X       (math-div (math-factorial (math-float n))
  1514. X             (math-mul (math-factorial m)
  1515. X                   (math-factorial (math-sub n m))))))
  1516. X    ((math-negp m) 0)
  1517. X    ((math-negp n)
  1518. X     (let ((val (math-choose (math-add (math-add n m) -1) m)))
  1519. X       (if (math-evenp (math-trunc m))
  1520. X           val
  1521. X         (math-neg val))))
  1522. X    ((and (math-num-integerp n)
  1523. X          (Math-lessp n m))
  1524. X     0)
  1525. X    (t
  1526. X     (let ((tm (math-trunc m)))
  1527. X       (or (integerp tm) (math-reject-arg tm 'fixnump))
  1528. X       (if (> tm 100)
  1529. X           (math-div (math-factorial (math-float n))
  1530. X             (math-mul (math-factorial (math-float m))
  1531. X                   (math-factorial (math-float
  1532. X                            (math-sub n m)))))
  1533. X         (math-with-extra-prec 1
  1534. X           (math-choose-float-iter tm n 1 '(float 1 0)))))))
  1535. X)
  1536. X(fset 'calcFunc-choose (symbol-function 'math-choose))
  1537. X
  1538. X(defun math-choose-iter (m n i c)
  1539. X  (if (= (% i 5) 1)
  1540. X      (math-working (format "choose(%d)" (1- i)) c))
  1541. X  (if (<= i m)
  1542. X      (math-choose-iter m (1- n) (1+ i)
  1543. X            (math-quotient (math-mul c n) i))
  1544. X    c)
  1545. X)
  1546. X
  1547. X(defun math-choose-float-iter (count n i c)
  1548. X  (if (= (% i 5) 1)
  1549. X      (math-working (format "choose(%d)" (1- i)) c))
  1550. X  (if (> count 0)
  1551. X      (math-choose-float-iter (1- count) (math-sub n 1) (1+ i)
  1552. X                  (math-div (math-mul c n) i))
  1553. X    c)
  1554. X)
  1555. X
  1556. X
  1557. X;;; Produce a random digit in the range 0..999.
  1558. X;;; Avoid various pitfalls that may lurk in the built-in (random) function!
  1559. X(defun math-random-digit ()
  1560. X  (prog1
  1561. X      (% (lsh (random math-first-random-flag) -4) 1000)
  1562. X    (setq math-first-random-flag nil))
  1563. X)
  1564. X(setq math-first-random-flag t)
  1565. X
  1566. X;;; Produce an N-digit random integer.
  1567. X(defun math-random-digits (n)
  1568. X  (cond ((<= n 6)
  1569. X     (math-scale-right (+ (* (math-random-digit) 1000) (math-random-digit))
  1570. X               (- 6 n)))
  1571. X    (t (let* ((slop (% (- 900003 n) 3))
  1572. X          (i (/ (+ n slop) 3))
  1573. X          (digs nil))
  1574. X         (while (> i 0)
  1575. X           (setq digs (cons (math-random-digit) digs)
  1576. X             i (1- i)))
  1577. X         (math-normalize (math-scale-right (cons 'bigpos digs)
  1578. X                           slop)))))
  1579. X)
  1580. X
  1581. X;;; Produce a uniformly-distributed random float 0 <= N < 1.
  1582. X(defun math-random-float ()
  1583. X  (math-make-float (math-random-digits calc-internal-prec)
  1584. X           (- calc-internal-prec))
  1585. X)
  1586. X
  1587. X;;; Produce a Gaussian-distributed random float with mean=0, sigma=1.
  1588. X(defun math-gaussian-float ()
  1589. X  (math-with-extra-prec 2
  1590. X    (if (and math-gaussian-cache
  1591. X         (= (car math-gaussian-cache) calc-internal-prec))
  1592. X    (prog1
  1593. X        (cdr math-gaussian-cache)
  1594. X      (setq math-gaussian-cache nil))
  1595. X      (let* ((v1 (math-add (math-mul (math-random-float) 2) -1))
  1596. X         (v2 (math-add (math-mul (math-random-float) 2) -1))
  1597. X         (r (math-add (math-sqr v1) (math-sqr v2))))
  1598. X    (while (or (not (Math-lessp r 1)) (math-zerop r))
  1599. X      (setq v1 (math-add (math-mul (math-random-float) 2) -1)
  1600. X        v2 (math-add (math-mul (math-random-float) 2) -1)
  1601. X        r (math-add (math-sqr v1) (math-sqr v2))))
  1602. X    (let ((fac (math-sqrt (math-mul (math-div (math-ln r) r) -2))))
  1603. X      (setq math-gaussian-cache (cons calc-internal-prec
  1604. X                      (math-mul v1 fac)))
  1605. X      (math-mul v2 fac)))))
  1606. X)
  1607. X(setq math-gaussian-cache nil)
  1608. X
  1609. X;;; Produce a random integer or real 0 <= N < MAX.
  1610. X(defun math-random (max)
  1611. X  (cond ((Math-zerop max)
  1612. X     (math-gaussian-float))
  1613. X    ((Math-integerp max)
  1614. X     (let* ((digs (math-numdigs max))
  1615. X        (r (math-random-digits (+ digs 3))))
  1616. X       (math-mod r max)))
  1617. X    ((Math-realp max)
  1618. X     (math-mul (math-random-float) max))
  1619. X    ((and (eq (car max) 'intv) (math-constp max)
  1620. X          (Math-lessp (nth 2 max) (nth 3 max)))
  1621. X     (if (math-floatp max)
  1622. X         (let ((val (math-add (math-mul (math-random-float)
  1623. X                        (math-sub (nth 3 max) (nth 2 max)))
  1624. X                  (nth 2 max))))
  1625. X           (if (or (and (memq (nth 1 max) '(0 1))      ; almost not worth
  1626. X                (math-equal val (nth 2 max)))  ;   checking!
  1627. X               (and (memq (nth 1 max) '(0 2))
  1628. X                (math-equal val (nth 3 max))))
  1629. X           (math-random max)
  1630. X         val))
  1631. X       (let ((lo (if (memq (nth 1 max) '(0 1))
  1632. X             (math-add (nth 2 max) 1) (nth 2 max)))
  1633. X         (hi (if (memq (nth 1 max) '(1 3))
  1634. X             (math-add (nth 3 max) 1) (nth 3 max))))
  1635. X         (if (Math-lessp lo hi)
  1636. X         (math-add (math-random (math-sub hi lo)) lo)
  1637. X           (math-reject-arg max "Empty interval")))))
  1638. X    (t (math-reject-arg max 'realp)))
  1639. X)
  1640. X(fset 'calcFunc-random (symbol-function 'math-random))
  1641. X
  1642. X
  1643. X;;; Check if the integer N is prime.  [X I]
  1644. X;;; Return (nil) if non-prime,
  1645. X;;;        (nil N) if non-prime with known factor N,
  1646. X;;;        (nil unknown) if non-prime with no known factors,
  1647. X;;;        (t) if prime,
  1648. X;;;        (maybe N P) if probably prime (after N iters with probability P%)
  1649. X(defun math-prime-test (n iters)
  1650. X  (if (and (Math-vectorp n) (cdr n))
  1651. X      (setq n (nth (1- (length n)) n)))
  1652. X  (if (Math-messy-integerp n)
  1653. X      (setq n (math-trunc n)))
  1654. X  (let ((res))
  1655. X    (while (> iters 0)
  1656. X      (setq res
  1657. X        (cond ((and (integerp n) (<= n 5003))
  1658. X           (list (= (math-next-small-prime n) n)))
  1659. X          ((not (Math-integerp n))
  1660. X           (error "Argument must be an integer"))
  1661. X          ((Math-integer-negp n)
  1662. X           '(nil))
  1663. X          ((Math-natnum-lessp n '(bigpos 0 0 8))
  1664. X           (setq n (math-fixnum n))
  1665. X           (let ((i -1) v)
  1666. X             (while (and (> (% n (setq v (aref math-primes-table
  1667. X                               (setq i (1+ i)))))
  1668. X                    0)
  1669. X                 (< (* v v) n)))
  1670. X             (if (= (% n v) 0)
  1671. X             (list nil v)
  1672. X               '(t))))
  1673. X          ((not (equal n (car math-prime-test-cache)))
  1674. X           (cond ((= (% (nth 1 n) 2) 0) '(nil 2))
  1675. X             ((= (% (nth 1 n) 5) 0) '(nil 5))
  1676. X             (t (let ((dig (cdr n)) (sum 0))
  1677. X                  (while dig
  1678. X                (if (cdr dig)
  1679. X                    (setq sum (% (+ (+ sum (car dig))
  1680. X                            (* (nth 1 dig) 1000))
  1681. X                         111111)
  1682. X                      dig (cdr (cdr dig)))
  1683. X                  (setq sum (% (+ sum (car dig)) 111111)
  1684. X                    dig nil)))
  1685. X                  (cond ((= (% sum 3) 0) '(nil 3))
  1686. X                    ((= (% sum 7) 0) '(nil 7))
  1687. X                    ((= (% sum 11) 0) '(nil 11))
  1688. X                    ((= (% sum 13) 0) '(nil 13))
  1689. X                    ((= (% sum 37) 0) '(nil 37))
  1690. X                    (t
  1691. X                     (setq math-prime-test-cache-k 1
  1692. X                       math-prime-test-cache-q
  1693. X                       (math-div2 n)
  1694. X                       math-prime-test-cache-nm1
  1695. X                       (math-add n -1))
  1696. X                     (while (math-evenp
  1697. X                         math-prime-test-cache-q)
  1698. X                       (setq math-prime-test-cache-k
  1699. X                         (1+ math-prime-test-cache-k)
  1700. X                         math-prime-test-cache-q
  1701. X                         (math-div2
  1702. X                          math-prime-test-cache-q)))
  1703. X                     (setq iters (1+ iters))
  1704. X                     (list 'maybe
  1705. X                       0
  1706. X                       (math-sub
  1707. X                        100
  1708. X                        (math-div
  1709. X                         '(float 232 0)
  1710. X                         (math-numdigs n))))))))))
  1711. X          ((not (eq (car (nth 1 math-prime-test-cache)) 'maybe))
  1712. X           (nth 1 math-prime-test-cache))
  1713. X          (t   ; Fermat step
  1714. X           (let* ((x (math-add (math-random (math-add n -2)) 2))
  1715. X              (y (math-pow-mod x math-prime-test-cache-q n))
  1716. X              (j 0))
  1717. X             (while (and (not (eq y 1))
  1718. X                 (not (equal y math-prime-test-cache-nm1))
  1719. X                 (< (setq j (1+ j)) math-prime-test-cache-k))
  1720. X               (setq y (math-mod (math-mul y y) n)))
  1721. X             (if (or (equal y math-prime-test-cache-nm1)
  1722. X                 (and (eq y 1) (eq j 0)))
  1723. X             (list 'maybe
  1724. X                   (1+ (nth 1 (nth 1 math-prime-test-cache)))
  1725. X                   (math-mul (nth 2 (nth 1 math-prime-test-cache))
  1726. X                     '(float 25 -2)))
  1727. X               '(nil unknown))))))
  1728. X      (setq math-prime-test-cache (list n res)
  1729. X        iters (if (eq (car res) 'maybe)
  1730. X              (1- iters)
  1731. X            0)))
  1732. X    res)
  1733. X)
  1734. X(defvar math-prime-test-cache '(-1))
  1735. X
  1736. X;;; Theory: summing base-10^6 digits modulo 111111 is "casting out 999999s".
  1737. X;;; Initial probability that N is prime is 1/ln(N) = log10(e)/log10(N).
  1738. X;;; After culling [2,3,5,7,11,13,37], probability of primality is 5.36 x more.
  1739. X;;; Initial reported probability of non-primality is thus 100% - this.
  1740. X;;; Each Fermat step multiplies this probability by 25%.
  1741. X;;; The Fermat step is algorithm P from Knuth section 4.5.4.
  1742. X
  1743. X
  1744. X(defun math-prime-factors (n)
  1745. X  (setq math-prime-factors-finished t)
  1746. X  (if (Math-messy-integerp n)
  1747. X      (setq n (math-trunc n)))
  1748. X  (if (and (Math-natnump n) (Math-natnum-lessp 2 n))
  1749. X      (let (factors res p (i 0))
  1750. X    (while (and (not (eq n 1))
  1751. X            (< i (length math-primes-table)))
  1752. X      (setq p (aref math-primes-table i))
  1753. X      (while (eq (cdr (setq res (cond ((eq n p) (cons 1 0))
  1754. X                      ((eq n 1) (cons 0 1))
  1755. X                      ((consp n) (math-idivmod n p))
  1756. X                      (t (cons (/ n p) (% n p))))))
  1757. X             0)
  1758. X        (math-working "factor" p)
  1759. X        (setq factors (nconc factors (list p))
  1760. X          n (car res)))
  1761. X      (or (eq n 1)
  1762. X          (Math-natnum-lessp p (car res))
  1763. X          (setq factors (nconc factors (list n))
  1764. X            n 1))
  1765. X      (setq i (1+ i)))
  1766. X    (or (setq math-prime-factors-finished (eq n 1))
  1767. X        (setq factors (nconc factors (list n))))
  1768. X    (cons 'vec factors))
  1769. X    (calc-record-why 'integerp n)
  1770. X    (list 'calcFunc-prfac n))
  1771. X)
  1772. X(fset 'calcFunc-prfac (symbol-function 'math-prime-factors))
  1773. X
  1774. X(defun math-totient (n)
  1775. X  (if (Math-messy-integerp n)
  1776. X      (setq n (math-trunc n)))
  1777. X  (if (Math-natnump n)
  1778. X      (if (Math-natnum-lessp n 2)
  1779. X      (if (Math-negp n)
  1780. X          (math-totient (math-abs n))
  1781. X        n)
  1782. X    (let ((factors (cdr (math-prime-factors n)))
  1783. X          p)
  1784. X      (if math-prime-factors-finished
  1785. X          (progn
  1786. X        (while factors
  1787. X          (setq p (car factors)
  1788. X            n (math-mul (math-div n p) (math-add p -1)))
  1789. X          (while (equal p (car factors))
  1790. X            (setq factors (cdr factors))))
  1791. X        n)
  1792. X        (calc-record-why "Number too big to factor" n)
  1793. X        (list 'calcFunc-totient n))))
  1794. X    (calc-record-why 'natnump n)
  1795. X    (list 'calcFunc-totient n))
  1796. X)
  1797. X(fset 'calcFunc-totient (symbol-function 'math-totient))
  1798. X
  1799. X(defun math-moebius (n)
  1800. X  (if (Math-messy-integerp n)
  1801. X      (setq n (math-trunc n)))
  1802. X  (if (and (Math-natnump n) (not (eq n 0)))
  1803. X      (if (Math-natnum-lessp n 2)
  1804. X      (if (Math-negp n)
  1805. X          (math-moebius (math-abs n))
  1806. X        1)
  1807. X    (let ((factors (cdr (math-prime-factors n)))
  1808. X          (mu 1))
  1809. X      (if math-prime-factors-finished
  1810. X          (progn
  1811. X        (while factors
  1812. X          (setq mu (if (equal (car factors) (nth 1 factors))
  1813. X                   0 (math-neg mu))
  1814. X            factors (cdr factors)))
  1815. X        mu)
  1816. X        (calc-record-why "Number too big to factor" n)
  1817. X        (list 'calcFunc-moebius n))))
  1818. X    (calc-record-why 'natnump n)
  1819. X    (list 'calcFunc-moebius n))
  1820. X)
  1821. X(fset 'calcFunc-moebius (symbol-function 'math-moebius))
  1822. X
  1823. X
  1824. X(defun math-next-prime (n iters)
  1825. X  (if (Math-integerp n)
  1826. X      (if (Math-integer-negp n)
  1827. X      2
  1828. X    (if (and (integerp n) (< n 5003))
  1829. X        (math-next-small-prime (1+ n))
  1830. X      (if (math-evenp n)
  1831. X          (setq n (math-add n -1)))
  1832. X      (let (res)
  1833. X        (while (not (car (setq res (math-prime-test
  1834. X                    (setq n (math-add n 2)) iters)))))
  1835. X        (if (and calc-verbose-nextprime
  1836. X             (eq (car res) 'maybe))
  1837. X        (calc-report-prime-test res)))
  1838. X      n))
  1839. X    (if (Math-realp n)
  1840. X    (math-next-prime (math-trunc n) iters)
  1841. X      (math-reject-arg n 'integerp)))
  1842. X)
  1843. X(fset 'calcFunc-nextprime (symbol-function 'math-next-prime))
  1844. X(setq calc-verbose-nextprime nil)
  1845. X
  1846. X(defun math-prev-prime (n iters)
  1847. X  (if (Math-integerp n)
  1848. X      (if (Math-lessp n 4)
  1849. X      2
  1850. X    (if (math-evenp n)
  1851. X        (setq n (math-add n 1)))
  1852. X    (let (res)
  1853. X      (while (not (car (setq res (math-prime-test
  1854. X                      (setq n (math-add n -2)) iters)))))
  1855. X      (if (and calc-verbose-nextprime
  1856. X           (eq (car res) 'maybe))
  1857. X          (calc-report-prime-test res)))
  1858. X    n)
  1859. X    (if (Math-realp n)
  1860. X    (math-prev-prime (math-ceiling n) iters)
  1861. X      (math-reject-arg n 'integerp)))
  1862. X)
  1863. X(fset 'calcFunc-prevprime (symbol-function 'math-prev-prime))
  1864. X
  1865. X(defun math-next-small-prime (n)
  1866. X  (if (and (integerp n) (> n 2))
  1867. X      (let ((lo -1)
  1868. X        (hi (length math-primes-table))
  1869. X        mid)
  1870. X    (while (> (- hi lo) 1)
  1871. X      (if (> n (aref math-primes-table
  1872. X             (setq mid (ash (+ lo hi) -1))))
  1873. X          (setq lo mid)
  1874. X        (setq hi mid)))
  1875. X    (aref math-primes-table hi))
  1876. X    2)
  1877. X)
  1878. X
  1879. X(defconst math-primes-table
  1880. X  [2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89
  1881. X     97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181
  1882. X     191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277
  1883. X     281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383
  1884. X     389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487
  1885. X     491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601
  1886. X     607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709
  1887. X     719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827
  1888. X     829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947
  1889. X     953 967 971 977 983 991 997 1009 1013 1019 1021 1031 1033 1039 1049
  1890. X     1051 1061 1063 1069 1087 1091 1093 1097 1103 1109 1117 1123 1129 1151
  1891. SHAR_EOF
  1892. echo "End of part 8"
  1893. echo "File calc-ext.el is continued in part 9"
  1894. echo "9" > s2_seq_.tmp
  1895. exit 0
  1896.